Object-Oriented Programming

We've talked about how everyting in Python is an object. In addition, we've come to use many objects. However, we have not created any objects. In this lecture, we will discuss object-oriented programming, and what we can achieve with it. Here is what we will cover:

1. Classes
    > Attributes
2. Methods
3. Inheritance

Let's take a look at the building block of creating an object - a class!

Class

The fundamental building block of an object, is the class. A class defines all of the specifications of an object, from its attributes, methods, and more. The declaration of a class begins with the "class" keyword.

class Name(superclass):
    // etc

We'll talk later about what superclass means. However, this is the opening statement for a class. Here's another example:


In [6]:
# Creating a class called Bike
class Bike:
    pass

If you do not already know, the word "instantiation" means to create a version of an object. Here is how we would instantiate a bike.


In [4]:
# An 'instance' of a bike
my_bike = Bike()
type(my_bike)


Out[4]:
__main__.Bike

Now, my_bike is an object reference to "Bike". This means that the variable doesn't actually hold the object in memory, but simply points to it.

Attribute

To give objects attributes (i.e. a bike's wheel size, speed, weight), you need to create the

__init__(attributes...)

function. This function is called whenever an object is instantiated. It's what assigns the values you want on an object. Let's see its use below.


In [7]:
class Bike:
    def __init__(self, speed, wheel, weight):
        self.speed = speed
        self.wheel = wheel
        self.weight = weight

What just happened? We created the init method in Bike, and provided it four parameters: self, speed, wheel, and weight. In the body of the method, we assigned self.attr to the attribute. First, let's discuss the self. The word self is actually not a keyword, but a type of requirement from Python. You see, all Python methods must have a reference to the object itself. You can use any name you like for that reference, but everyone uses the word "self" because it is simply convention.

The attributes in this class are speed, wheel, and weight. In the method body, we set the referenced object's attribute value to... well... itself (or, in other words, whatever was sent in). Let's try an instantiation below.


In [12]:
# Instantiating a Bike Object
woo = Bike(2, 4, 5)

The instantiation checks out. Here's what happened:

self.speed = 2
self.wheel = 4
self.weight = 5

This allows us to use dot notation to access the properties. How do we get the wheel size of the bike? We use the following notation:

object.attr

It's that simple.


In [13]:
woo.speed


Out[13]:
2

In [14]:
woo.wheel


Out[14]:
4

In [15]:
woo.weight


Out[15]:
5

Methods

We've discussed functions numerous amounts of times, and methods are essentially the same thing but written inside of functions. We can use attribute values now, instead.


In [27]:
class Bike:
    # __init__() function
    def __init__(self, speed, wheel, weight):
        self.speed = speed
        self.wheel = wheel
        self.weight = weight
        
    # A method calculates the max weight of a person on the bike
    def max_weight(self, rider_weight):
        max_weight = rider_weight * self.weight
        return max_weight
    
    # Another method
    def some_method(self):
        pass

In [28]:
woo = Bike(2, 4, 5)

In [29]:
woo.max_weight(30)


Out[29]:
150

Special Methods

There are a few methods in Python that you can alter in your class referred to as "special methods". These methods allow you to control certain behaviors that happen behind the scenes in your program. Things like printing your object, or how it reacts to operators, etc can be controlled via these methods. Let's look at a few.


In [30]:
class Bike():
    def __init__(self, speed, wheel, weight):
        self.speed = speed
        self.wheel = wheel
        self.weight = weight
        
    def __str__(self):
        return "Bike Speed: {}  Wheel Size: {}  Weight: {}".format(self.speed, self.wheel, self.weight)

In [31]:
woo = Bike(3, 4, 5)

In [32]:
print(woo)


Bike Speed: 3  Wheel Size: 4  Weight: 5